Optimize exposes of partial insensitive images.
authorHavoc Pennington <hp@redhat.com>
Tue, 29 Jan 2002 23:59:21 +0000 (23:59 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Tue, 29 Jan 2002 23:59:21 +0000 (23:59 +0000)
Tue Jan 29 18:50:59 2002  Owen Taylor  <otaylor@redhat.com>

        * gtk/gtkimage.c (gtk_image_expose): Optimize exposes of
        partial insensitive images.

2002-01-24  Havoc Pennington  <hp@redhat.com>

        * gtk/gtkimage.c (gtk_image_expose): create insensitive version of
        the image regardless of storage type, #63305

        * demos/gtk-demo/images.c: add toggle button to demonstrate that
        GtkImage makes its contents insensitive

ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
demos/gtk-demo/images.c
gtk/gtkimage.c

index 935139b74b99249467bac9ec539f71ec966fcd6b..e7729798d025a5f3377c1040bc909ddf86a00254 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Tue Jan 29 18:50:59 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkimage.c (gtk_image_expose): Optimize exposes of
+       partial insensitive images.
+
+2002-01-24  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtkimage.c (gtk_image_expose): create insensitive version of
+       the image regardless of storage type, #63305
+
+       * demos/gtk-demo/images.c: add toggle button to demonstrate that
+       GtkImage makes its contents insensitive
+
 Tue Jan 29 17:40:02 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_to_drawable):
index 935139b74b99249467bac9ec539f71ec966fcd6b..e7729798d025a5f3377c1040bc909ddf86a00254 100644 (file)
@@ -1,3 +1,16 @@
+Tue Jan 29 18:50:59 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkimage.c (gtk_image_expose): Optimize exposes of
+       partial insensitive images.
+
+2002-01-24  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtkimage.c (gtk_image_expose): create insensitive version of
+       the image regardless of storage type, #63305
+
+       * demos/gtk-demo/images.c: add toggle button to demonstrate that
+       GtkImage makes its contents insensitive
+
 Tue Jan 29 17:40:02 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_to_drawable):
index 935139b74b99249467bac9ec539f71ec966fcd6b..e7729798d025a5f3377c1040bc909ddf86a00254 100644 (file)
@@ -1,3 +1,16 @@
+Tue Jan 29 18:50:59 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkimage.c (gtk_image_expose): Optimize exposes of
+       partial insensitive images.
+
+2002-01-24  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtkimage.c (gtk_image_expose): create insensitive version of
+       the image regardless of storage type, #63305
+
+       * demos/gtk-demo/images.c: add toggle button to demonstrate that
+       GtkImage makes its contents insensitive
+
 Tue Jan 29 17:40:02 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_to_drawable):
index 935139b74b99249467bac9ec539f71ec966fcd6b..e7729798d025a5f3377c1040bc909ddf86a00254 100644 (file)
@@ -1,3 +1,16 @@
+Tue Jan 29 18:50:59 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkimage.c (gtk_image_expose): Optimize exposes of
+       partial insensitive images.
+
+2002-01-24  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtkimage.c (gtk_image_expose): create insensitive version of
+       the image regardless of storage type, #63305
+
+       * demos/gtk-demo/images.c: add toggle button to demonstrate that
+       GtkImage makes its contents insensitive
+
 Tue Jan 29 17:40:02 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_to_drawable):
index 935139b74b99249467bac9ec539f71ec966fcd6b..e7729798d025a5f3377c1040bc909ddf86a00254 100644 (file)
@@ -1,3 +1,16 @@
+Tue Jan 29 18:50:59 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkimage.c (gtk_image_expose): Optimize exposes of
+       partial insensitive images.
+
+2002-01-24  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtkimage.c (gtk_image_expose): create insensitive version of
+       the image regardless of storage type, #63305
+
+       * demos/gtk-demo/images.c: add toggle button to demonstrate that
+       GtkImage makes its contents insensitive
+
 Tue Jan 29 17:40:02 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_to_drawable):
index 935139b74b99249467bac9ec539f71ec966fcd6b..e7729798d025a5f3377c1040bc909ddf86a00254 100644 (file)
@@ -1,3 +1,16 @@
+Tue Jan 29 18:50:59 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkimage.c (gtk_image_expose): Optimize exposes of
+       partial insensitive images.
+
+2002-01-24  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtkimage.c (gtk_image_expose): create insensitive version of
+       the image regardless of storage type, #63305
+
+       * demos/gtk-demo/images.c: add toggle button to demonstrate that
+       GtkImage makes its contents insensitive
+
 Tue Jan 29 17:40:02 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_to_drawable):
index 935139b74b99249467bac9ec539f71ec966fcd6b..e7729798d025a5f3377c1040bc909ddf86a00254 100644 (file)
@@ -1,3 +1,16 @@
+Tue Jan 29 18:50:59 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkimage.c (gtk_image_expose): Optimize exposes of
+       partial insensitive images.
+
+2002-01-24  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/gtkimage.c (gtk_image_expose): create insensitive version of
+       the image regardless of storage type, #63305
+
+       * demos/gtk-demo/images.c: add toggle button to demonstrate that
+       GtkImage makes its contents insensitive
+
 Tue Jan 29 17:40:02 2002  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkpixbuf-render.c (gdk_pixbuf_render_to_drawable):
index 4719f484edfa63ccaf207d1edbc903a7f4c5cead..bbab57ba0d87fecef8bfb9ba12687309e78c8b45 100644 (file)
@@ -41,12 +41,13 @@ progressive_prepared_callback (GdkPixbufLoader *loader,
   gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
 }
 
-static void progressive_updated_callback (GdkPixbufLoader *loader,
-                                         gint             x,
-                                         gint             y,
-                                         gint             width,
-                                         gint             height,
-                                         gpointer         data)
+static void
+progressive_updated_callback (GdkPixbufLoader *loader,
+                              gint                x,
+                              gint                y,
+                              gint                width,
+                              gint                height,
+                              gpointer    data)
 {
   GtkWidget *image;
   
@@ -280,6 +281,31 @@ cleanup_callback (GtkObject *object,
   image_stream = NULL;
 }
 
+static void
+toggle_sensitivity_callback (GtkWidget *togglebutton,
+                             gpointer   user_data)
+{
+  GtkContainer *container = user_data;
+  GList *list;
+  GList *tmp;
+  
+  list = gtk_container_get_children (container);
+
+  tmp = list;
+  while (tmp != NULL)
+    {
+      /* don't disable our toggle */
+      if (GTK_WIDGET (tmp->data) != togglebutton)
+        gtk_widget_set_sensitive (GTK_WIDGET (tmp->data),
+                                  !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (togglebutton)));
+      
+      tmp = tmp->next;
+    }
+
+  g_list_free (list);
+}
+  
+
 GtkWidget *
 do_images (void)
 {
@@ -288,6 +314,7 @@ do_images (void)
   GtkWidget *image;
   GtkWidget *label;
   GtkWidget *align;
+  GtkWidget *button;
   GdkPixbuf *pixbuf;
   GError *error = NULL;
   char *filename;
@@ -410,6 +437,14 @@ do_images (void)
       gtk_container_add (GTK_CONTAINER (frame), image);
 
       start_progressive_loading (image);
+
+      /* Sensitivity control */
+      button = gtk_toggle_button_new_with_mnemonic ("_Insensitive");
+      gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+      g_signal_connect (G_OBJECT (button), "toggled",
+                        G_CALLBACK (toggle_sensitivity_callback),
+                        vbox);
     }
 
   if (!GTK_WIDGET_VISIBLE (window))
index a429d8691b354faa15b7e94a2d74d47cd35776c6..fc72560745c5d4eea8d04401e86543ca82caeb05 100644 (file)
@@ -1197,7 +1197,7 @@ gtk_image_expose (GtkWidget      *widget,
   g_return_val_if_fail (GTK_IS_IMAGE (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
   
-  if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget) &&
+  if (GTK_WIDGET_MAPPED (widget) &&
       GTK_IMAGE (widget)->storage_type != GTK_IMAGE_EMPTY)
     {
       GtkImage *image;
@@ -1205,12 +1205,18 @@ gtk_image_expose (GtkWidget      *widget,
       GdkRectangle area, image_bound;
       gfloat xalign;
       gint x, y;
-      GdkBitmap *mask = NULL;
-      GdkPixbuf *stock_pixbuf = NULL;
+      GdkBitmap *mask;
+      GdkPixbuf *pixbuf;
+      gboolean needs_state_transform;
       
       image = GTK_IMAGE (widget);
       misc = GTK_MISC (widget);
 
+      area = event->area;
+      
+      if (!gdk_rectangle_intersect (&area, &widget->allocation, &area))
+       return FALSE;
+
       if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
        xalign = misc->xalign;
       else
@@ -1225,7 +1231,13 @@ gtk_image_expose (GtkWidget      *widget,
       
       image_bound.x = x;
       image_bound.y = y;      
+      image_bound.width = 0;
+      image_bound.height = 0;      
 
+      mask = NULL;
+      pixbuf = NULL;
+      needs_state_transform = GTK_WIDGET_STATE (widget) != GTK_STATE_NORMAL;
+      
       switch (image->storage_type)
         {
         case GTK_IMAGE_PIXMAP:
@@ -1233,33 +1245,83 @@ gtk_image_expose (GtkWidget      *widget,
           gdk_drawable_get_size (image->data.pixmap.pixmap,
                                  &image_bound.width,
                                  &image_bound.height);
+
+         if (gdk_rectangle_intersect (&image_bound, &area, &image_bound) &&
+             needs_state_transform)
+            {
+              pixbuf = gdk_pixbuf_get_from_drawable (NULL,
+                                                     image->data.pixmap.pixmap,
+                                                     gtk_widget_get_colormap (widget),
+                                                     image_bound.x, image_bound.y,
+                                                    0, 0,
+                                                     image_bound.width,
+                                                     image_bound.height);
+
+             x = image_bound.x;
+             y = image_bound.y;
+            }
+         
           break;
 
         case GTK_IMAGE_IMAGE:
           mask = image->mask;
           image_bound.width = image->data.image.image->width;
           image_bound.height = image->data.image.image->height;
+
+         if (gdk_rectangle_intersect (&image_bound, &area, &image_bound) &&
+             needs_state_transform)
+            {
+              pixbuf = gdk_pixbuf_get_from_image (NULL,
+                                                  image->data.image.image,
+                                                  gtk_widget_get_colormap (widget),
+                                                 image_bound.x - x, image_bound.y - y,
+                                                  0, 0,
+                                                  image_bound.width,
+                                                  image_bound.height);
+
+             x = image_bound.x;
+             y = image_bound.y;
+            }
           break;
 
         case GTK_IMAGE_PIXBUF:
           image_bound.width = gdk_pixbuf_get_width (image->data.pixbuf.pixbuf);
-          image_bound.height = gdk_pixbuf_get_height (image->data.pixbuf.pixbuf);
+          image_bound.height = gdk_pixbuf_get_height (image->data.pixbuf.pixbuf);          
+
+         if (gdk_rectangle_intersect (&image_bound, &area, &image_bound) &&
+             needs_state_transform)
+           {
+             pixbuf = gdk_pixbuf_new_subpixbuf (image->data.pixbuf.pixbuf,
+                                                image_bound.x - x, image_bound.y - y,
+                                                image_bound.width, image_bound.height);
+
+             x = image_bound.x;
+             y = image_bound.y;
+           }
+         else
+           {
+             pixbuf = image->data.pixbuf.pixbuf;
+             g_object_ref (G_OBJECT (pixbuf));
+           }
           break;
 
         case GTK_IMAGE_STOCK:
-          stock_pixbuf = gtk_widget_render_icon (widget,
-                                                 image->data.stock.stock_id,
-                                                 image->icon_size,
-                                                 NULL);
-          if (stock_pixbuf)
+          pixbuf = gtk_widget_render_icon (widget,
+                                           image->data.stock.stock_id,
+                                           image->icon_size,
+                                           NULL);
+          if (pixbuf)
             {              
-              image_bound.width = gdk_pixbuf_get_width (stock_pixbuf);
-              image_bound.height = gdk_pixbuf_get_height (stock_pixbuf);
+              image_bound.width = gdk_pixbuf_get_width (pixbuf);
+              image_bound.height = gdk_pixbuf_get_height (pixbuf);
             }
+
+          /* already done */
+          needs_state_transform = FALSE;
           break;
 
         case GTK_IMAGE_ICON_SET:
-          stock_pixbuf =
+          pixbuf =
             gtk_icon_set_render_icon (image->data.icon_set.icon_set,
                                       widget->style,
                                       gtk_widget_get_direction (widget),
@@ -1268,11 +1330,14 @@ gtk_image_expose (GtkWidget      *widget,
                                       widget,
                                       NULL);
 
-          if (stock_pixbuf)
+          if (pixbuf)
             {
-              image_bound.width = gdk_pixbuf_get_width (stock_pixbuf);
-              image_bound.height = gdk_pixbuf_get_height (stock_pixbuf);
+              image_bound.width = gdk_pixbuf_get_width (pixbuf);
+              image_bound.height = gdk_pixbuf_get_height (pixbuf);
             }
+
+          /* already done */
+          needs_state_transform = FALSE;
           break;
 
         case GTK_IMAGE_ANIMATION:
@@ -1290,10 +1355,18 @@ gtk_image_expose (GtkWidget      *widget,
 
             image_bound.width = gdk_pixbuf_animation_get_width (image->data.anim.anim);
             image_bound.height = gdk_pixbuf_animation_get_height (image->data.anim.anim);
+                  
+            /* don't advance the anim iter here, or we could get frame changes between two
+             * exposes of different areas.
+             */
+            
+            pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (image->data.anim.iter);
+            g_object_ref (G_OBJECT (pixbuf));
           }
           break;
-          
-        default:
+
+        case GTK_IMAGE_EMPTY:
+          g_assert_not_reached ();
           break;
         }
 
@@ -1303,95 +1376,97 @@ gtk_image_expose (GtkWidget      *widget,
          gdk_gc_set_clip_origin (widget->style->black_gc, x, y);
        }
 
-      area = event->area;
-      
-      if (gdk_rectangle_intersect (&area, &widget->allocation, &area) &&
-          gdk_rectangle_intersect (&image_bound, &area, &image_bound))
+      if (gdk_rectangle_intersect (&image_bound, &area, &image_bound))
         {
-          switch (image->storage_type)
+          if (pixbuf)
             {
-            case GTK_IMAGE_PIXMAP:
-              gdk_draw_drawable (widget->window,
-                                 widget->style->black_gc,
-                                 image->data.pixmap.pixmap,
-                                 image_bound.x - x, image_bound.y - y,
-                                 image_bound.x, image_bound.y,
-                                 image_bound.width, image_bound.height);
-              break;
-              
-            case GTK_IMAGE_IMAGE:
-              gdk_draw_image (widget->window,
-                              widget->style->black_gc,
-                              image->data.image.image,
-                              image_bound.x - x, image_bound.y - y,
-                              image_bound.x, image_bound.y,
-                              image_bound.width, image_bound.height);
-              break;
-
-            case GTK_IMAGE_PIXBUF:
-              gdk_pixbuf_render_to_drawable_alpha (image->data.pixbuf.pixbuf,
-                                                   widget->window,
-                                                   image_bound.x - x,
-                                                   image_bound.y - y,
-                                                   image_bound.x,
-                                                   image_bound.y,
-                                                   image_bound.width,
-                                                   image_bound.height,
-                                                   GDK_PIXBUF_ALPHA_FULL,
-                                                   128,
-                                                   GDK_RGB_DITHER_NORMAL,
-                                                   0, 0);
-              break;
-
-            case GTK_IMAGE_STOCK: /* fall thru */
-            case GTK_IMAGE_ICON_SET:
-              if (stock_pixbuf)
+              if (needs_state_transform)
                 {
-                  gdk_pixbuf_render_to_drawable_alpha (stock_pixbuf,
-                                                       widget->window,
-                                                       image_bound.x - x,
-                                                       image_bound.y - y,
-                                                       image_bound.x,
-                                                       image_bound.y,
-                                                       image_bound.width,
-                                                       image_bound.height,
-                                                       GDK_PIXBUF_ALPHA_FULL,
-                                                       128,
-                                                       GDK_RGB_DITHER_NORMAL,
-                                                       0, 0);
+                  GtkIconSource *source;
+                  GdkPixbuf *rendered;
+
+                  source = gtk_icon_source_new ();
+                  gtk_icon_source_set_pixbuf (source, pixbuf);
+                  /* The size here is arbitrary; since size isn't
+                   * wildcarded in the souce, it isn't supposed to be
+                   * scaled by the engine function
+                   */
+                  gtk_icon_source_set_size (source,
+                                            GTK_ICON_SIZE_SMALL_TOOLBAR);
+                  gtk_icon_source_set_size_wildcarded (source, FALSE);
                   
-                  g_object_unref (G_OBJECT (stock_pixbuf));
+                  rendered = gtk_style_render_icon (widget->style,
+                                                    source,
+                                                    gtk_widget_get_direction (widget),
+                                                    GTK_WIDGET_STATE (widget),
+                                                    /* arbitrary */
+                                                    GTK_ICON_SIZE_SMALL_TOOLBAR,
+                                                    widget,
+                                                    "gtk-image");
+
+                  gtk_icon_source_free (source);
+
+                  g_object_unref (G_OBJECT (pixbuf));
+                  pixbuf = rendered;
                 }
-              break;
 
-            case GTK_IMAGE_ANIMATION:
-              /* don't advance the anim iter here, or we could get frame changes between two
-               * exposes of different areas.
-               */
-              
-              gdk_pixbuf_render_to_drawable_alpha (gdk_pixbuf_animation_iter_get_pixbuf (image->data.anim.iter),
-                                                   widget->window,
-                                                   image_bound.x - x,
-                                                   image_bound.y - y,
-                                                   image_bound.x,
-                                                   image_bound.y,
-                                                   image_bound.width,
-                                                   image_bound.height,
-                                                   GDK_PIXBUF_ALPHA_FULL,
-                                                   128,
-                                                   GDK_RGB_DITHER_NORMAL,
-                                                   0, 0);
-              break;
+              if (pixbuf)
+                {
+                  gdk_pixbuf_render_to_drawable (pixbuf,
+                                                widget->window,
+                                                widget->style->black_gc,                                                
+                                                image_bound.x - x,
+                                                image_bound.y - y,
+                                                image_bound.x,
+                                                image_bound.y,
+                                                image_bound.width,
+                                                image_bound.height,
+                                                GDK_RGB_DITHER_NORMAL,
+                                                0, 0);
+
+                  g_object_unref (G_OBJECT (pixbuf));
+                  pixbuf = NULL;
+                }
+            }
+          else
+            {
+              switch (image->storage_type)
+                {
+                case GTK_IMAGE_PIXMAP:
+                  gdk_draw_drawable (widget->window,
+                                     widget->style->black_gc,
+                                     image->data.pixmap.pixmap,
+                                     image_bound.x - x, image_bound.y - y,
+                                     image_bound.x, image_bound.y,
+                                     image_bound.width, image_bound.height);
+                  break;
               
-            default:
-              break;
+                case GTK_IMAGE_IMAGE:
+                  gdk_draw_image (widget->window,
+                                  widget->style->black_gc,
+                                  image->data.image.image,
+                                  image_bound.x - x, image_bound.y - y,
+                                  image_bound.x, image_bound.y,
+                                  image_bound.width, image_bound.height);
+                  break;
+
+                case GTK_IMAGE_PIXBUF:
+                case GTK_IMAGE_STOCK:
+                case GTK_IMAGE_ICON_SET:
+                case GTK_IMAGE_ANIMATION:
+                case GTK_IMAGE_EMPTY:
+                  g_assert_not_reached ();
+                  break;
+                }
             }
         } /* if rectangle intersects */      
+
       if (mask)
         {
           gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
           gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
         }
+      
     } /* if widget is drawable */
 
   return FALSE;